<template>
	<div>
		<input type="file" @change="fileChange" />
		<div class="btn">
			<el-button type="primary" @click="uploadBtn">点击上传</el-button>
			<el-button type="primary" @click="handleClose">停止上传</el-button>
		</div>
		<div class="progress">
			<el-progress :text-inside="true" :stroke-width="24" :percentage="percentage" status="success" />
		</div>
	</div>
</template>

<script setup>
import { ref } from "vue"
import SparkMD5 from "spark-md5"
import { ElMessage } from "element-plus"
import { ylRequest2 } from "@/service/index"
import axios from "axios"
//存放切片文件
const fileList = ref([])
const fileMd5 = ref("")
const file = ref(null)
let percentage = ref(0)
const CancelToken = axios.CancelToken
const source = CancelToken.source()
// 点击上传
const fileChange = e => {
	//分片
	file.value = e.target.files[0]
	percentage.value = 0
}
//切片函数
const uploadBtn = () => {
	if (!file.value) {
		return ElMessage({
			message: "请选择文件",
			type: "warning"
		})
	}
	//切片
	// 切片大小为1M
	for (let i = 0; i < file.value.size; i += 1024 * 1024) {
		fileList.value.push(file.value.slice(i, i + 1024 * 1024))
	}
	const hash = new SparkMD5.ArrayBuffer() // 构建hash值对象
	const fileReader = new FileReader()
	fileReader.onload = () => {
		hash.append(fileReader.result)
		fileMd5.value = hash.end()
		upload(0)
	}
	fileReader.readAsArrayBuffer(file.value)
}

const upload = async index => {
	if (index == fileList.value.length) {
		mergeUpload()
		return
	}
	const extname = file.value.type.split("/").pop()
	const formData = new FormData()
	formData.append("chunk", fileList.value[index])
	formData.append("index", index)
	formData.append("name", fileMd5.value + "@" + index) // 名字
	formData.append("filename", fileMd5.value) // 文件名
	formData.append("extname", extname) // 后缀
	try {
		const res = await ylRequest2.post({
			url: "/uploadFile",
			data: formData,
			cancelToken: source.token
		})
		if (res.code == 300) {
			//证明已经存在部分文件
			percentage.value = ((res.index / fileList.value.length) * 100).toFixed(2)
			upload(res.index + 1)
			ElMessage({
				message: res.msg,
				type: "info"
			})
		} else if (res.code == 200) {
			percentage.value = (((index + 1) / fileList.value.length) * 100).toFixed(2)
			upload(index + 1)
		} else if (res.code == 301) {
			percentage.value = 100
			ElMessage({
				message: res.msg,
				type: "warning"
			})
		} else {
			upload(index)
		}
	} catch (error) {
		console.log("axios error", error.message)
		console.log("ylRequest2", ylRequest2)
	}
}

const mergeUpload = async () => {
	//合并请求
	let res = await ylRequest2.post({
		url: "/merge_chunk",
		data: {
			filename: fileMd5.value,
			extname: file.value.type.split("/").pop()
		}
	})
	if ((res.code = 200)) {
		file.value = null
		fileList.value = []
		fileMd5.value = ""
		ElMessage({
			type: "success",
			message: "上传成功"
		})
	}
}
const handleClose = () => {
	source.cancel("取消")
}
</script>

<style lang="less" scoped></style>
